home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / CPPTASK.ARJ / TASK.HPP < prev    next >
C/C++ Source or Header  |  1991-08-21  |  11KB  |  361 lines

  1. /*
  2.    CPPTask - A Multitasking Kernel For C++
  3.  
  4.    TASK.HPP - Type and Class definitions and global routine prototypes.
  5.  
  6.    Version 1.0 08-12-91
  7.  
  8.    Ported by Rich Smith from:
  9.  
  10.    Public Domain Software written by
  11.       Thomas Wagner
  12.       Patschkauer Weg 31
  13.       D-1000 Berlin 33
  14.       West Germany
  15. */
  16.  
  17.  
  18. #include "tskconf.hpp"
  19. #include <stdio.h>
  20. #include <dos.h>
  21.  
  22. #define _Near
  23. #define TURBO  1
  24. #define MSC    0
  25.  
  26. #define local static      // Comment out the "static" for debugging
  27.  
  28. typedef unsigned char byte;
  29. typedef unsigned short word;
  30. typedef unsigned long dword;
  31. typedef void (cdecl far *funcptr)();
  32. typedef void far *farptr;
  33. typedef byte far *byteptr;
  34. typedef word far *wordptr;
  35.  
  36. #define TTIMEOUT ((farptr) -1L)
  37. #define TWAKE    ((farptr) -2L)
  38.  
  39. // Task states
  40.  
  41. #define  ST_KILLED   0
  42. #define  ST_STOPPED  1
  43. #define  ST_DELAYED  2
  44. #define  ST_WAITING  3
  45. #define  ST_ELIGIBLE 4
  46. #define  ST_RUNNING  5
  47.  
  48. // Task flags
  49.  
  50. #define  F_TEMP   0x80     // Task is temporary, free on kill
  51. #define  F_STTEMP 0x40     // Task stack is temporary, free on kill
  52. #define  F_CRIT   0x01     // Task is critical, may not be preempted
  53.  
  54. #define  FL_SYSM  0xf0     // Mask for system flags
  55. #define  FL_USRM  0x0f     // Mask for user flags
  56.  
  57. // Timer queue element states
  58.  
  59. #define  TSTAT_REMOVE      -1    // Remove element from queue
  60. #define  TSTAT_IDLE        0     // Not in queue
  61. #define  TSTAT_COUNTDOWN   1     // Count down timeout, then remove
  62. #define  TSTAT_REPEAT      2     // Count down, reload when done
  63.  
  64. // Timer queue element control structure pointer kinds
  65.  
  66. #define  TKIND_NULL        0     // NULL timer, used for deleted task
  67. #define  TKIND_TASK        1     // tcbptr, Wakeup associated task
  68. #define  TKIND_WAKE        2     // tcbptr, but not same task
  69. #define  TKIND_PROC        3     // call function
  70. #define  TKIND_FLAG        4     // flagptr, set flag
  71. #define  TKIND_COUNTER     5     // counterptr, increment counter
  72.  
  73. #define  TKIND_TEMP        0x80  // Hi bit set means temporary element
  74.  
  75. extern "C" {
  76.    void asm_schedule(void);
  77.    void asm_c_schedule(void);
  78.    int tsk_dis_int(void);
  79.    void tsk_ena_int(int);
  80.    void tsk_nop(void);
  81. }
  82.  
  83. class task;    // forward reference
  84. typedef task far *tcbptr;
  85.  
  86. typedef tcbptr far *tqueptr;
  87.  
  88. class timer; // forward reference
  89. typedef timer far *tlinkptr;
  90.  
  91. class timer {
  92.    tlinkptr next;
  93.    dword    timeout;    // Timeout counter
  94.    dword    reload;     // Timeout counter reload value
  95.    farptr   strucp;     // Pointer to control structure
  96.    byte     tstate;     // Element state
  97.    byte     tkind;      // Kind of control structure
  98.    void     tsk_timer_action (void);
  99.    friend   local void far timer_main (void);
  100.    friend   task;
  101. public:
  102.    timer(dword tout, farptr strucp, byte kind, byte rept);
  103.    ~timer(void);
  104.    void change_timer(dword tout, byte rept);
  105. };
  106.  
  107. class tasker_class {
  108. public:
  109.    tasker_class(byte varpri, int speedup);
  110.    ~tasker_class(void);
  111.    void preempt_on(void);
  112.    void preempt_off(void);
  113.    void far schedule(void);
  114.    void far c_schedule(void); 
  115.    void tsk_dis_preempt(void);
  116.    void tsk_ena_preempt(void);
  117. };
  118.  
  119. class task {
  120. // private data members
  121.    tcbptr   next;       // Next in queue
  122.    tqueptr  queue;      // Queue head pointer
  123.    byteptr  stack;      // Task stack
  124.    byteptr  stkbot;     // Task stack bottom
  125.    word     prior;      // Task priority
  126.    word     initprior;  // Initial Task priority
  127.    byte     state;      // Task state
  128.    byte     flags;      // Task flags
  129.    timer   *timerq;     // Timer queue link
  130.    farptr   retptr;     // Event return pointer
  131.    int      retsize;    // Return buffer size for pipes
  132. // private member functions
  133.    friend int  far t_delay(dword ticks);
  134.    friend void far tsk_wait (tqueptr que, dword timeout);
  135.    friend void     killretn(void);
  136.    friend void far tsk_kill_queue(tqueptr que);
  137.    void            tsk_kill(void);
  138.    void            tsk_wakeup(void);
  139. public:
  140.    task(funcptr func, byteptr stack, word stksz,
  141.         word priority, farptr arg);
  142.    ~task(void);
  143.    void* operator new(size_t size);
  144.    int start_task(void);
  145.    int wake_task(void);
  146.    void tsk_enqueue(tqueptr que);
  147.    void tsk_unqueue(void);
  148.    void tsk_enqtimer(dword tout);
  149.    void tsk_unqtimer(void);
  150.    tcbptr tsk_runable(void);
  151.  
  152.    void set_priority(word newprior);
  153.    word get_priority(void);
  154.    void set_state(byte newstate) { state = newstate; }
  155.    byte get_state(void) { return state; }
  156.    void set_user_flags(byte newflags);
  157.    void set_system_flags(byte newflags);
  158.    byte get_flags(void) { return flags; }
  159.    void set_retptr(farptr newptr) { retptr = newptr; }
  160.    farptr get_retptr(void) { return retptr; }
  161.    void set_retsize(int newsize) { retsize = newsize; }
  162.    int get_retsize(void) { return retsize; }
  163.    tcbptr get_next(void) { return next; }
  164. };
  165.  
  166. class resource {
  167.    tcbptr  waiting;   // queue for tasks waiting for resource
  168.    tcbptr   owner;    // current owner of the resource
  169.    int      state;    // resource state
  170.    byte     flags;    // resource flags
  171. public:
  172.    resource();
  173.    ~resource(void);
  174.    void release_resource(void);
  175.    int request_resource(dword timeout);
  176.    int c_request_resource(void);
  177.    int check_resource(void);
  178.    int get_state(void) { return state; }
  179.    byte get_flags(void) { return flags; }
  180. };
  181.  
  182. typedef resource far *resourceptr;
  183.  
  184. class flag {
  185.    tcbptr   wait_set;     // queue for tasks waiting for flag to be set
  186.    tcbptr   wait_clear;   // queue for tasks waiting for flag to be cleared
  187.    int      state;        // flag state
  188.    byte     flags;        // flag flags
  189. public:
  190.    flag();
  191.    ~flag(void);
  192.    void set_flag(void);
  193.    void clear_flag(void);
  194.    int wait_flag_set(dword timeout);
  195.    int wait_flag_clear(dword timeout);
  196.    int clear_flag_wait_set(dword timeout);
  197.    int check_flag(void);
  198. };
  199.  
  200. typedef flag far *flagptr;
  201.  
  202. class counter {
  203.    tcbptr   wait_set;    // queue for tasks waiting for counter to be set
  204.    tcbptr   wait_clear;  // queue for tasks waiting for counter to be cleared
  205.    dword    state;       // counter state
  206.    byte     flags;       // counter flags
  207. public:
  208.    counter();
  209.    ~counter(void);
  210.    void set_flag(void);
  211.    void clear_counter(void);
  212.    int wait_counter_set(dword timeout);
  213.    int wait_counter_clear(dword timeout);
  214.    void inc_counter(void);
  215.    dword check_counter(void);
  216. };
  217.  
  218. typedef counter far *counterptr;
  219.  
  220. struct msg_header {
  221.    struct msg_header far *next;
  222. };
  223.  
  224. typedef struct msg_header far *msgptr;
  225.  
  226. class mailbox {
  227.    tcbptr   waiting;     // queue for tasks waiting for mail
  228.    msgptr   mail_first;  // pointer to first message in mailbox
  229.    msgptr   mail_last;   // pointer to last message in mailbox
  230.    byte     flags;       // mailbox flags
  231. public:
  232.    mailbox();
  233.    ~mailbox(void);
  234.    void send_mail(farptr msg);
  235.    farptr wait_mail(dword timeout);
  236.    farptr c_wait_mail(void);
  237.    int check_mailbox(void);
  238. };
  239.  
  240. typedef mailbox far *mailboxptr;
  241.  
  242. class pipe {
  243.    tcbptr    wait_read;    // queue for tasks blocked on read
  244.    tcbptr    wait_write;   // queue for tasks blocked on write
  245.    tcbptr    wait_clear;   // queue for tasks waiting for pipe to be clear
  246.    word      bufsize;      // size of pipe buffer
  247.    word      filled;       // number of bytes in the pipe
  248.    word      inptr;        // head pointer for circular buffer
  249.    word      outptr;       // tail pointer for circular buffer
  250.    byteptr   contents;     // pointer to pipe contents
  251.    byte      flags;        // pipe flags
  252.  
  253. // private member functions
  254.    byte      tsk_getcpipe ();
  255.    void      tsk_putcpipe (byte c);
  256. public:
  257.    pipe(farptr buf, word buffersize);
  258.    ~pipe(void);
  259.    int read_pipe(dword timeout);
  260.    int c_read_pipe(void);
  261.    int write_pipe(byte ch, dword timeout);
  262.    int c_write_pipe(byte ch);
  263.    int wait_pipe_empty(dword timeout);
  264.    int check_pipe(void);
  265.    word pipe_free(void);
  266.    void flush_pipe(void);
  267.    word get_bufsize(void) { return bufsize; }
  268.    word get_filled(void) { return filled; }
  269.    byte get_flags(void) { return flags; }
  270. };
  271.  
  272. typedef pipe far *pipeptr;
  273.  
  274. class wpipe {
  275.    tcbptr    wait_read;    // queue for tasks blocked on read
  276.    tcbptr    wait_write;   // queue for tasks blocked on write
  277.    tcbptr    wait_clear;   // queue for tasks waiting for pipe to be clear
  278.    word      bufsize;      // size of pipe buffer
  279.    word      filled;       // number of words in the pipe
  280.    word      inptr;        // head pointer for circular buffer
  281.    word      outptr;       // tail pointer for circular buffer
  282.    wordptr   wcontents;    // pointer to pipe contents
  283.    byte      flags;        // pipe flags
  284.  
  285. // private member functions
  286.    word      tsk_getwpipe ();
  287.    void      tsk_putwpipe (word c);
  288. public:
  289.    wpipe(farptr buf, word buffersize);
  290.    ~wpipe(void);
  291.    word read_wpipe(dword timeout);
  292.    word c_read_wpipe(void);
  293.    int write_wpipe(word ch, dword timeout);
  294.    int c_write_wpipe(word ch);
  295.    int wait_wpipe_empty(dword timeout);
  296.    word check_wpipe(void);
  297.    word wpipe_free(void);
  298.    void flush_wpipe(void);
  299.    word get_bufsize(void) { return bufsize; }
  300.    word get_filled(void) { return filled; }
  301.    byte get_flags(void) { return flags; }
  302. };
  303.  
  304. typedef wpipe far *wpipeptr;
  305.  
  306. class buffer {
  307.    resource    buf_write;  // write buffer resource
  308.    resource    buf_read;   // read buffer resource
  309.    wpipe       pip;        // pipe used to implement buffer
  310.    word        msgcnt;     // number of messages in buffer
  311.    byte        flags;      // buffer flags
  312.  
  313. // private member function
  314.    int         tsk_wrbuf (word w, dword timeout);
  315. public:
  316.    buffer(farptr buf, word bufsize);
  317.    ~buffer(void);
  318.    int read_buffer(farptr msg, int size, dword timeout);
  319.    int c_read_buffer(farptr msg, int size);
  320.    int write_buffer(farptr msg, int size, dword timeout);
  321.    int c_write_buffer(farptr msg, int size);
  322.    word check_buffer(void);
  323. };
  324.  
  325. typedef buffer far *bufferptr;
  326.  
  327. // create definitions for critical code section handling
  328.  
  329. #define CRITICAL  int crit_intsav
  330. #define C_ENTER   crit_intsav = tsk_dis_int()
  331. #define C_LEAVE   tsk_ena_int (crit_intsav)
  332.  
  333.  
  334. extern void far tsk_kill_queue(tqueptr);
  335.  
  336. extern farptr tsk_alloc (word size);
  337. extern void tsk_free (farptr item);
  338. extern resource alloc_resource;
  339.  
  340. // provide "C" linkage for routines to be called from assemply language
  341.  
  342. extern "C" void far asm_remove_tasker(void);
  343. extern "C" void far asm_inc_counter(counterptr cnt);
  344. extern "C" void far asm_set_flag(flagptr flg);
  345. extern "C" void far asm_clear_flag(flagptr flg);
  346. extern "C" int far asm_wait_flag_clear(flagptr flg, dword timeout);
  347. extern "C" int far asm_request_resource(resourceptr rsc, dword timeout);
  348. extern "C" void far asm_release_resource(resourceptr rsc);
  349. extern "C" word far asm_read_wpipe(wpipeptr pip, dword timeout);
  350. extern "C" word far asm_check_wpipe(wpipeptr pip);
  351. extern "C" int far asm_c_write_wpipe(wpipeptr pip, word ch);
  352.  
  353. extern task main_tcb;
  354. extern tasker_class tasker;
  355.  
  356. inline void tsk_cli(void) { disable(); }
  357. inline void tsk_sti(void) { enable(); }
  358. inline void tsk_outp(int port, byte b) { outportb(port, b); }
  359. inline byte tsk_inp(int port) { return ((byte) inportb(port)); }
  360.  
  361.